package net.wansho.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Author：汤小洋
 * Date：2023-11-03 10:41
 * Description：<描述>
 */
@Configuration
public class RabbitMqConfig {

    @Value("${shop.exchange}")
    private String exchange;

    @Value("${shop.queue}")
    private String queue;

    @Value("${shop.routingKey}")
    private String routingKey;

    @Bean
    public Exchange exchange(){
        return new DirectExchange(exchange);
    }

    @Bean
    public Queue queue(){
        return new Queue(queue);
    }

    @Bean
    public Binding binding(Queue queue, Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with(routingKey).noargs();
    }

    /**
     * 消息转换器
     */
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 消息可靠性
     */
    @Resource
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        // 设置消息确认的回调，即消息到达交换机时回调
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack){
                // System.out.println("消息成功到达交换机。。。。。。。" + correlationData.getId());
            }else {
                System.out.println("消息没有到达交换机。。。。。。。" + cause);
            }
        });

        // 设置消息回退的回调，即消息未到达队列时回调
        rabbitTemplate.setReturnsCallback(returned -> {
            System.out.println("消息未到达队列。。。。。。。" + returned.getMessage() + "," + returned.getReplyCode() + "," + returned.getReplyText());
        });

    }


    /**
     * 死信队列
     */
    @Bean
    public Exchange normalExchange(){
        return new DirectExchange("normal.exchange");
    }

    @Bean
    public Queue normalQueue(){
        Map<String, Object> arguments =new HashMap<>();
        arguments.put("x-max-length",1); // 设置队列中消息的最大数量
        arguments.put("x-message-ttl",100); // 设置队列中消息的过期时间，单位毫秒
        arguments.put("x-dead-letter-exchange","dead.exchange"); // 设置死信交换机
        arguments.put("x-dead-letter-routing-key","dead.key"); // 设置死信路由键

        return new Queue("normal.queue",true,false,false,arguments); // 队列名，是否持久化，是否排他，是否自动删除，其他参数
    }

    @Bean
    public Binding normalBinding(){
        return BindingBuilder.bind(normalQueue()).to(normalExchange()).with("normal.key").noargs();
    }

    @Bean
    public Exchange deadExchange(){
        return new DirectExchange("dead.exchange");
    }

    @Bean
    public Queue deadQueue(){
        return new Queue("dead.queue");
    }

    @Bean
    public Binding deadBinding(){
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead.key").noargs();
    }

}
